package maze.view;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Map;

import org.lwjgl.opengl.GL11;

public class Texture
{
	private static Map<String, Integer> textureMap = new HashMap<String, Integer>();

	public static final int loadTexture(String name)
	{
		// check if we already loaded this texture
		Integer textureId = textureMap.get(name);
		if (textureId != null)
		{
			return textureId;
		}

		// if not found, load now
		String path = "texture/" + name + ".png";
		Image image = (new javax.swing.ImageIcon(path)).getImage();

		// Exctract The Image
		BufferedImage tex = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_3BYTE_BGR);
		Graphics2D g = (Graphics2D) tex.getGraphics();
		g.drawImage(image, null, null);
		g.dispose();

		// Flip Image
		AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
		tx.translate(0, -image.getHeight(null));
		AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
		tex = op.filter(tex, null);

		// Put Image In Memory
		ByteBuffer scratch = ByteBuffer.allocateDirect(4 * tex.getWidth() * tex.getHeight());

		byte data[] = (byte[]) tex.getRaster().getDataElements(0, 0, tex.getWidth(), tex.getHeight(), null);
		scratch.clear();
		scratch.put(data);
		scratch.rewind();

		// Create A IntBuffer For Image Address In Memory
		IntBuffer buf = ByteBuffer.allocateDirect(4).order(ByteOrder.nativeOrder()).asIntBuffer();
		GL11.glGenTextures(buf); // Create Texture In OpenGL

		GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(0));
		// Typical Texture Generation Using Data From The Image

		// Linear Filtering
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
		// Linear Filtering
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
		// Generate The Texture
		GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, tex.getWidth(), tex.getHeight(), 0, GL11.GL_RGB,
				GL11.GL_UNSIGNED_BYTE, scratch);

		// add the texture to the map
		textureMap.put(name, buf.get(0));

		// Return Image Address In Memory
		return buf.get(0);
	}
}
